/* eslint-disable no-console */
const GitClient = require('simple-git/promise');
const fs = require('fs-extra');
const path = require('path');
const utility = require('../phoenix/models/utility');

const [bareRepoPath, newRepoPath] = process.argv.slice(2);

if (!bareRepoPath) {
  console.log('Miss parameter 1(bare repo path)');
  process.exit(1);
}
if (!newRepoPath) {
  console.log('Miss parameter 2(dest repo path)');
  process.exit(1);
}
if (!fs.existsSync(bareRepoPath)) {
  console.log('Bare repo path not exists');
  process.exit(1);
}
fs.ensureDir(newRepoPath)
  .then(() => fs.readdir(bareRepoPath))
  .then((files) => utility.arrayChunkOperation(files, 1, (userId) => {
    if (!userId.match(/^[0-9a-z]{24}$/)) {
      return Promise.resolve();
    }
    return fs.readdir(path.join(bareRepoPath, userId))
      .then((gitRepos) => utility.arrayChunkOperation(gitRepos, 1, (projectId) => {
        if (!projectId.match(/^[0-9a-z]{24}\.git$/)) {
          return Promise.resolve();
        }
        const destDir = path.join(newRepoPath, userId, projectId.replace('.git', ''));
        let git;
        if (fs.existsSync(destDir)) {
          console.log(`update repo ${path.join(bareRepoPath, userId, projectId)}`);
          git = new GitClient(destDir);
          return git.branch()
            .then(({ all: branches }) => utility.arrayChunkOperation(branches, 1, (branch) => {
              const match = branch.match(/^remotes\/origin\/([a-f0-9]+$)/);
              if (!match) {
                return Promise.resolve();
              }
              console.log(`sync branch ${match[1]}`);
              return git.checkout(match[1])
                .then(() => git.pull()).catch(() => {});
            }));
        }
        git = new GitClient(newRepoPath);
        console.log(`clone repo ${path.join(bareRepoPath, userId, projectId)}`);
        return git.clone(path.join(bareRepoPath, userId, projectId), destDir);
      }));
  }))
  .catch((err) => {
    console.log(err.message);
  });
